package com.linkoog.devtools.code_generator.wizard.generate.database.table.custom;

import com.linkoog.devtools.code_generator.database.domain.TableInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.ui.table.JBTable;
import com.linkoog.devtools.intellij.ui.table.cell_editor.JCheckBoxTableCellEditor;
import com.linkoog.devtools.intellij.ui.table.cell_reander.JCheckBoxTableCellRenderer;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class DbtableInfoJTableModel extends AbstractTableModel implements Serializable {

    private static final Logger logger = Logger.getInstance(DbtableInfoJTableModel.class);

    private final List<String> columnList = Arrays.asList("表名","选中");

    private final List<TableInfo> dataList = new ArrayList<>();

    private List<TableInfo> tempDataList;


    public DbtableInfoJTableModel(){
    }

    public DbtableInfoJTableModel(Collection<TableInfo> newRowList) {
        addRow(newRowList);
    }

    public void initTableColumn(JBTable jbTable){
        DefaultTableCellRenderer tableCellRenderer = new DefaultTableCellRenderer();
        tableCellRenderer.setHorizontalAlignment(SwingConstants.LEFT);
        tableCellRenderer.setBackground(Color.LIGHT_GRAY);

        int tableNameIndex = 0;
        TableColumn tableNameColumn = jbTable.getColumn(columnList.get(tableNameIndex));
        tableNameColumn.setMinWidth(150);
        tableNameColumn.setMaxWidth(150);
        tableNameColumn.setPreferredWidth(150);
        tableNameColumn.setCellRenderer(tableCellRenderer);


        /*int tableCommentIndex = 1;
        TableColumn tableCommentColumn = jbTable.getColumn(columnList.get(tableCommentIndex));
        tableCommentColumn.setMinWidth(65);
        tableCommentColumn.setMaxWidth(65);
        tableCommentColumn.setPreferredWidth(65);
        tableCommentColumn.setCellRenderer(tableCellRenderer);*/


        int checkIndex = 1;
        TableColumn checkColumn = jbTable.getColumn(columnList.get(checkIndex));
        checkColumn.setCellEditor(new JCheckBoxTableCellEditor());
        checkColumn.setCellRenderer(new JCheckBoxTableCellRenderer());
        checkColumn.setMinWidth(48);
        checkColumn.setMaxWidth(48);
        checkColumn.setPreferredWidth(48);

        // 表头全选
        //final MyCheckBoxRenderer check = new MyCheckBoxRenderer();
        final JCheckBoxTableCellRenderer check = new JCheckBoxTableCellRenderer();
        check.setIgnoreCellValue(true);
        checkColumn.setHeaderRenderer(check);
        jbTable.getTableHeader().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e){
                //如果点击的是第5列，即checkbox这一列
                if(jbTable.getColumnModel().getColumnIndexAtX(e.getX()) == checkIndex){
                    boolean b = !check.isSelected();
                    check.setSelected(b);

                    DbtableInfoJTableModel tableModel = DbtableInfoJTableModel.this;
                    List<TableInfo> tableInfoList = tableModel.getAllDataList();
                    for (TableInfo tableInfo : tableInfoList) {
                        tableInfo.setChecked(b);
                    }
                    jbTable.getTableHeader().repaint();
                    tableModel.fireTableDataChanged();
                }
            }
        });

    }


    @Override
    public int getRowCount() {
        return dataList.size();
    }

    @Override
    public int getColumnCount() {
        return columnList.size();
    }

    @Override
    public String getColumnName(int columnIndex) {
        /*if (columnIndex == 4){
            return "";
        }*/
        return columnList.get(columnIndex);
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        TableInfo tableInfo = dataList.get(rowIndex);
        switch (columnIndex){
            case 0: return tableInfo.getTableName();
            case 1: return tableInfo.isChecked();
        }
        return null;
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        switch (columnIndex){
            case 1:  return true;
        }
        return false;
    }

    @Override
    public Class getColumnClass(int c)	{
        Object value = getValueAt(1, c);
        if(value!=null){
            return value.getClass();
        } else {
            return super.getClass();
        }
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        TableInfo tableInfo = dataList.get(rowIndex);
        switch (columnIndex){
            case 1:
                tableInfo.setChecked((Boolean) aValue);
                break;
        }
    }

    public final boolean hasElements() {
        return dataList.size() > 0;
    }


    public final void addRow(@NotNull TableInfo newRow) {
        dataList.add(newRow);
        super.fireTableDataChanged();
    }

    public final void addRow(@NotNull Collection<TableInfo> newRowList) {
        tempDataList = null;
        if (newRowList != null && !newRowList.isEmpty()){
            dataList.addAll(newRowList);
        }
        super.fireTableDataChanged();
    }

    public final void removeRow(int rowIndex) {
        dataList.remove(rowIndex);
        super.fireTableDataChanged();
    }

    public final void rowCheck(int rowIndex) {
        TableInfo tableInfo = dataList.get(rowIndex);
        tableInfo.setChecked(!tableInfo.isChecked());
        super.fireTableDataChanged();
    }

    public final void clear() {
        dataList.clear();
        super.fireTableDataChanged();
    }

    public final void reset(@NotNull Collection<TableInfo> newRowList) {
        dataList.clear();
        tempDataList = null;
        if (newRowList != null && !newRowList.isEmpty()){
            dataList.addAll(newRowList);
        }
        super.fireTableDataChanged();
    }


    public final TableInfo getRowData(int rowIndex) {
        return dataList.get(rowIndex);
    }

    public List<String> getColumnList() {
        return columnList;
    }

    public List<TableInfo> getCheckedRow(){
        return dataList.stream()
                .filter(tableInfo -> tableInfo.isChecked())
                .map(TableInfo::deepCopyWithCheckColumn)
                .collect(Collectors.toList());
    }




    public void filter(String tableName){
        if (tempDataList == null){
            tempDataList = new ArrayList<>(dataList);
        }


        if (tempDataList.size() == 0){
            return;
        }

        List<TableInfo> list;
        if (StringUtils.isNotBlank(tableName)){
            list = tempDataList.stream()
                    .filter(tableInfo -> tableInfo.getTableName().contains(tableName))
                    .collect(Collectors.toList());
        } else {
            list = tempDataList;
        }

        dataList.clear();
        dataList.addAll(list);
        super.fireTableDataChanged();
    }

    public List<TableInfo> getAllDataList() {
        if (tempDataList == null){
            return dataList;
        } else {
            return tempDataList;
        }
    }
}
